package dev;
import google.visualization.OrgChart;
import jstm.Host;

/**
 * EventScopes for mouse events
 * 
 * TODO:
	 * add scrolling and dragging?
 * @author Cref
 */

class MouseEvents {

	//TODO: add optional rightButton:Bool
	public static function whenToggled(parentScope:EventScope, elm:HTMLElement) return betweenEvents(parentScope, elm, 'click')
	public static function whenMouseDown(parentScope:EventScope, elm:HTMLElement) return betweenEvents(parentScope, elm, 'mousedown', elm.ownerDocument, 'mouseup')
	public static function whenMouseHover(parentScope:EventScope, elm:HTMLElement) return betweenEvents(parentScope, elm, 'mouseenter', 'mouseleave')
	
	public static function betweenCalls(parentScope:EventScope,c1:Dynamic,?c2:Dynamic) {
		var scope:EventScope = null;
		if (c2 == null) c2 = c1;
		return scope=parentScope.createEventScope(function(setActive:Bool->Void) {
			var cancel=function(e:Event) setActive(false);
			parentScope.after(c1, function(e:Event) {
				setActive(true);
				scope.after(c2, cancel);//self-cancelling listener
			});
		});
	}
	
	public static function betweenEvents(parentScope:EventScope, obj1:org.w3c.dom.events.EventTarget,e1:String,?obj2:org.w3c.dom.events.EventTarget,?e2:String) {
		var scope:EventScope = null;
		if (obj2 == null) obj2 = obj1;
		if (e2 == null) e2 = e1;
		return scope=parentScope.createEventScope(function(setActive:Bool->Void) {
			var cancel=function(e:Event) setActive(false);
			parentScope.on(obj1, e1, function(e:Event) {
				setActive(true);
				scope.on(obj2, e2, cancel);//self-cancelling listener
			});
		});
	}
	
	//NOTE: Chrome fires mousemove events when the mouse isn't moving but is still over the element. this can be fixed here by checking coordinates but should be fixed in Chrome
	//TODO: write mousecursor coordinates to some variable
	public static function whenMouseMoves(parentScope:EventScope, elm:HTMLElement,timeout=500) {
		var scope:EventScope = null;
		return scope=parentScope.createEventScope(function(setActive:Bool->Void) {
			var cancel=function() setActive(false);
			parentScope.on(elm, 'mousemove', function(e) {
				setActive(true);
				scope.delayed(cancel, timeout, true);
			});
		});
	}
	
	public static function during(parentScope:EventScope, timeMsec:Int) {
		var sA,scope = parentScope.createEventScope(function(setActive:Bool->Void) sA = setActive);
		parentScope.onStart(function(){
			sA(true);
			scope.delayed(function() sA(false), timeMsec)();
		});
		return scope;
	}
}